import store from '@/store'
import config from '@/config'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { toast, showConfirm, tansParams } from '@/utils/common'

let timeout = 10000
const baseUrl = config.baseUrl

const upload = config => {
  // 是否需要设置 token
  const isToken = (config.headers || {}).isToken === false
  config.header = config.header || {}
  if (getToken() && !isToken) {
    config.header['Authorization'] = 'Bearer ' + getToken()
  }
  // get请求映射params参数
  if (config.params) {
    let url = config.url + '?' + tansParams(config.params)
    url = url.slice(0, -1)
    config.url = url
  }
  return new Promise((resolve, reject) => {
      const uploadTask = uni.uploadFile({
        timeout: config.timeout || timeout,
        url: baseUrl + config.url,
        filePath: config.filePath,
        name: config.name || 'file',
        header: config.header,
        formData: config.formData,
        success: (res) => {
          let result = JSON.parse(res.data)
          const code = result.code || 200
          const msg = errorCode[code] || result.msg || errorCode['default']
          if (code === 200) {
            resolve(result)
          } else if (code == 401) {
            showConfirm("登录状态已过期，您可以继续留在该页面，或者重新登录?").then(res => {
              if (res.confirm) {
                store.dispatch('LogOut').then(res => {
                  uni.reLaunch({ url: '/pages/login/login' })
                })
              }
            })
            reject('无效的会话，或者会话已过期，请重新登录。')
          } else if (code === 500) {
            toast(msg)
            reject('500')
          } else if (code !== 200) {
            toast(msg)
            reject(code)
          }
        },
        fail: (error) => {
          // uni.uploadFile 的 error 对象通常包含 errMsg 属性
          let errorMsg = ''
          if (error) {
            errorMsg = String(error.errMsg || error.message || error.msg || '')
          }
          
          // 确保 errorMsg 是字符串类型
          errorMsg = String(errorMsg || '上传失败，请重试')
          
          // 处理常见的错误信息
          if (typeof errorMsg === 'string' && errorMsg.trim()) {
            const lowerMsg = errorMsg.toLowerCase()
            if (lowerMsg.includes('network error') || lowerMsg.includes('network')) {
              errorMsg = '网络连接异常，请检查网络后重试'
            } else if (lowerMsg.includes('timeout') || lowerMsg.includes('超时')) {
              errorMsg = '上传超时，文件可能过大，请尝试压缩后上传或选择较小的文件'
            } else if (lowerMsg.includes('fail')) {
              // 提取具体的失败原因
              const match = errorMsg.match(/fail\s+(.+)/i)
              if (match && match[1] && match[1] !== 'undefined' && match[1].trim()) {
                errorMsg = '上传失败: ' + match[1].trim()
              } else if (lowerMsg.includes('undefined') || lowerMsg === 'uploadfile:fail undefined') {
                // 对于 undefined 错误，可能是文件过大、超时或服务器拒绝
                const fileSize = config.filePath ? '（可能是文件过大或超时）' : ''
                errorMsg = '上传失败，请检查文件大小和网络连接' + fileSize + '。建议压缩后重试'
              } else {
                errorMsg = '上传失败，请检查文件后重试'
              }
            }
          } else {
            errorMsg = '上传失败，请重试'
          }
          
          // 创建标准化的错误对象
          const errorObj = {
            errMsg: errorMsg,
            message: errorMsg,
            originalError: error,
            filePath: config.filePath
          }
          
          console.error('上传失败:', {
            originalError: error,
            filePath: config.filePath,
            timeout: config.timeout,
            processedMsg: errorMsg
          })
          toast(errorMsg)
          reject(errorObj)
        }
      })

      // 进度回调
      if (uploadTask && typeof config.onProgress === 'function') {
        try {
          uploadTask.onProgressUpdate((res) => {
            const progress = res && typeof res === 'object' ? (res.progress || 0) : (res || 0)
            config.onProgress(progress)
          })
        } catch (e) {
          console.error('上传进度回调错误:', e)
        }
      }
      // 透出任务句柄（用于取消）
      if (typeof config.onTask === 'function') {
        try { 
          config.onTask(uploadTask) 
        } catch (e) {
          console.error('设置上传任务句柄失败:', e)
        }
      }
  })
}

export default upload
